#ifndef XMLERRHANDLER_H
#define XMLERRHANDLER_H

#include "xercesc/dom/DOM.hpp"
#include "xercesc/util/XMLString.hpp"
#include "xercesc/util/XercesDefs.hpp"
#include "XmlDefs.h"
#include <iostream>
#include "XmlUtil.h"
#include <boost/shared_ptr.hpp>

namespace xerces {

class XmlLocator : public DOMLocator {
 public:
  XmlLocator(const DOMLocator& dl)
    {
      setLineNumber(dl.getLineNumber());
      setColumnNumber(dl.getColumnNumber());
      setOffset(dl.getOffset());
      setErrorNode(dl.getErrorNode());
      setURI(dl.getURI());
    }
  XMLSSize_t getLineNumber() const
  {
    return lnnumber;
  }
  
  XMLSSize_t getColumnNumber() const
  {
    return clnumber;
  }
  
  XMLSSize_t getOffset() const
  {
    return offset;
  }
  DOMNode* getErrorNode() const
  {
    return node;
  }
  const XMLCh* getURI() const
  {
    return (const XMLCh*)uri.get();
  }
  
  void setLineNumber(const XMLSSize_t ln)
  {
    lnnumber = ln;
  }
  
  void setColumnNumber(const XMLSSize_t cl)
  {
    clnumber = cl;
  }
  
  void setOffset(const XMLSSize_t off)
  {
    offset = off;
  }
  
  void setErrorNode(DOMNode* const errNode)
  {
    if(node)
      node = errNode;
  }
  
  void setURI(const XMLCh* const u)
  {

    uri = boost::shared_ptr<XMLCh>(new XMLCh( *u ));

  }
  ~XmlLocator() {}
 
 private:
  
  XMLSSize_t lnnumber;
  XMLSSize_t clnumber;
  XMLSSize_t offset;
  DOMNode* node;
  boost::shared_ptr<XMLCh> uri;
  
};


class XmlError : public DOMError {
 public:
  XmlError(const DOMError&e)
    {
      setSeverity(e.getSeverity());
      setMessage(e.getMessage());
      setLocation(e.getLocation());
      setRelatedException(e.getRelatedException());
      setType(e.getType());
      setRelatedData(e.getRelatedData());
    }

  XmlError()
    {
      setSeverity( DOMError::DOM_SEVERITY_WARNING );
      setMessage( NULL );
      setLocation( NULL );
      setRelatedException( NULL );
      setType( NULL );
      setRelatedData( NULL );
    }

  short getSeverity() const
  {
    return severity;
  }
  
  const XMLCh* getMessage() const
  {
    return (const XMLCh*)msg.get();
  }
  
  DOMLocator* getLocation() const
  {
    return loc.get();
  }
  
  void* getRelatedException() const
  {
    // No support for platform dependent exception
    return NULL;
  }
  const XMLCh* getType() const
  {
    return (const XMLCh*)type.get();
  }
  
  void* getRelatedData() const
  {
    // No support for platform dependent exception
    // therefore no related data required
    return NULL;
  } 
  
  void setSeverity(const short sev)
  {
    severity = static_cast<ErrorSeverity>(sev);
  }
  
  void setMessage(const XMLCh* const message)
  {
    if( message )
      msg = boost::shared_ptr<XMLCh>( new XMLCh( *message ) );

  }
  
  void setLocation(DOMLocator* const location)
  {
    if( location )
      loc = boost::shared_ptr<XmlLocator>( new XmlLocator(*location) ); 
  }
  
  void setRelatedException(void* exc) const
  {
    // No support for platform dependent exception 
    return;
  }
  
  void setType(const XMLCh* typ)
  {
    if( typ )
      type = boost::shared_ptr<XMLCh>( new XMLCh( *typ ) );

  }
  
  void setRelatedData(void* relatedData)
  {
    // No support for platform dependent exception
    // therefore no related data required
    return;
  }
  
  ~XmlError() {}
  
  private:
  
  enum ErrorSeverity severity;
  boost::shared_ptr<XMLCh> msg;
  boost::shared_ptr<XmlLocator> loc;
  boost::shared_ptr<XMLCh> type;
  
  
  };
  
  
  class XmlErrorHandler: public xerces::XmlError, public DOMErrorHandler {
  public:
    
    XmlErrorHandler() {}
    

    ~XmlErrorHandler() {}
    
    /*     XmlErrorHandler::XmlStatusCode status(); */
    
    /* std::string translate(); */
    
    bool handleError(const DOMError&);

  };

  
}; //  end of namespace xerces

#endif
